在上一篇文章中,我们已经使用Django和DRF成功构建了基本API。 在这篇文章中,我们将添加身份验证并准备好我们的API。接下来我们将使用 Django-allauth, 因为能节省我们完全从头开始编写用户模型的时间, Django rest auth将我们的allauth模型转换为JSON可序列化。
让我们先安装:
1 |
pip install django-allauth==0.42.0 django-rest-auth==0.9.5 |
然后将这些应用程序添加到api / Settings.py中的“中
Django-allauth使用用户名作为必填且唯一的字段,我想通过将BaseUserManager扩展到我们的CustomUserManager来用电子邮件覆盖该用户名。 我们还需要超级用户一些额外的字段。
将此添加到Managers.py文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from django.contrib.auth.base_user import BaseUserManager from django.utils.translation import ugettext_lazy as _ class CustomUserManager(BaseUserManager): """ Custom user model manager where email is the unique identifiers for authentication instead of usernames. """ def create_user(self, email, password, **extra_fields): """ Create and save a User with the given email and password. """ if not email: raise ValueError(_('The Email must be set')) email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) user.save() return user def create_superuser(self, email, password, **extra_fields): """ Create and save a SuperUser with the given email and password. """ extra_fields.setdefault('is_staff', True) extra_fields.setdefault('is_superuser', True) extra_fields.setdefault('is_active', True) if extra_fields.get('is_staff') is not True: raise ValueError(_('Superuser must have is_staff=True.')) if extra_fields.get('is_superuser') is not True: raise ValueError(_('Superuser must have is_superuser=True.')) return self.create_user(email, password, **extra_fields) |
通过子类化AbstractUser,使电子邮件成为唯一标识符。 在此为用户提供我们的模型文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from django.db import models # Create your models here. from django.contrib.auth.models import AbstractUser from django.utils.translation import ugettext_lazy as _ from .managers import CustomUserManager class CustomUser(AbstractUser): username = None email = models.EmailField(_('email address'), unique=True) USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] objects = CustomUserManager() profile_name = models.CharField(blank=True, max_length=100) avatar = models.ImageField(upload_to='avatars/', null=True, blank=True) def set_avatar(self): avatar = self.avatar if not avatar: self.avatar="------REPLACE THIS WITH YOUR DEFAULT AVATAR URL-----" def __str__(self): return self.email |
现在是时候使用rest框架序列化我们的模型了。
1 2 3 4 5 6 7 8 |
from rest_framework import serializers from users.models import CustomUser class UserSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ['id', 'email', 'profile_name', 'avatar',] |
更新api / urls.py文件,将用户网址扩展到api urls.py中:
1 2 3 4 5 6 7 |
from django.conf.urls import url from django.conf import settings from allauth.account.views import confirm_email url(r'^rest-auth/', include('rest_auth.urls')), url(r'^rest-auth/registration/', include('rest_auth.registration.urls')), url(r'^account/', include('allauth.urls')), url(r'^accounts-rest/registration/account-confirm-email/(?P<key>.+)/$', confirm_email, name='account_confirm_email'), |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#Now add this to api/settings.py AUTH_USER_MODEL = 'users.CustomUser' ACCOUNT_USER_MODEL_USERNAME_FIELD = None #setting email field as required one ACCOUNT_EMAIL_REQUIRED = True ACCOUNT_UNIQUE_EMAIL = True ACCOUNT_USERNAME_REQUIRED = False ACCOUNT_AUTHENTICATION_METHOD = 'email' #change optional to mandatory to mandate email verification. ACCOUNT_EMAIL_VERIFICATION = 'optional' ACCOUNT_CONFIRM_EMAIL_ON_GET = True #Change these to set custom page to redirect user after email verification. ACCOUNT_EMAIL_CONFIRMATION_ANONYMOUS_REDIRECT_URL = '/' ACCOUNT_EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = '/ SITE_ID = 1 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' AUTHENTICATION_BACKENDS = ( # default 'django.contrib.auth.backends.ModelBackend', # email login 'allauth.account.auth_backends.AuthenticationBackend', ) |
到目前如何没有任何错误,我们就可以注册一个帐户并登录试试了。
导航到http://127.0.0.1:8000/rest-auth/register/进行注册
http://127.0.0.1:8000/rest-auth/login/登录
http://127.0.0.1:8000/rest-auth/user/以显示用户详细信息
接下来一步就是要使用jwt了, Django allauth已经为每个用户提供会话密钥,你可能会问为什么使用JWT呢? 因为jwt的结构可以帮助我们通过签名来验证用户。 Jwt有两个tokens access和refresh token。 他们的名字本身说明了他们的所作所为。 访问令牌是短暂的(尽管可以自定义5分钟左右)。 refresh token令牌的寿命长,通常在24小时内到期,也可以自定义。 您需要使用登录凭据来refresh token以进行r刷新。
让我们安装jwt
1 |
pip install djangorestframework-jwt==1.11.0 |
安装后,导航到API并编辑settings.py并添加它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( # By default we set everything to admin, # then open endpoints on a case-by-case basis 'rest_framework.permissions.IsAdminUser', ), 'TEST_REQUEST_RENDERER_CLASSES': ( 'rest_framework.renderers.MultiPartRenderer', 'rest_framework.renderers.JSONRenderer', 'rest_framework.renderers.TemplateHTMLRenderer' ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', ), #sets the pagination to the API endpoint 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 20, } from datetime import timedelta JWT_AUTH = { 'JWT_ALLOW_REFRESH': True, 'JWT_EXPIRATION_DELTA': timedelta(hours=1), #expires in 1 day you can change according to your needs 'JWT_REFRESH_EXPIRATION_DELTA': timedelta(days=1), } |
现在将它们添加到api / urls.py
1 2 |
url(r'^api/v1/auth/obtain_token/', obtain_jwt_token), url(r'^api/v1/auth/refresh_token/', refresh_jwt_token), |
导航到http://127.0.0.1:8000/api/v1/auth/obtain_token/以获取令牌,这时候我们输入用户名和密码返回的将是一个token字符串,用这个token去访问音乐文件。
现在,在音乐视图中取消注释permission_classes =(permissions.IsAuthenticated,)行,这仅允许经过身份验证的用户
截止目前我们已经使用Django,DRF,JWT成功构建了这个项目的后端。
GIT仓库:
https://github.com/Adarshreddyash/ronix-backend
https://github.com/Adarshreddyash/ronix-frontend